/**
 * com Inc
 * Copyright (c) 2014-2015 All Rights Reserved.
 */
package com.hightech.apidoc.common.commons.httpclient;

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;

import com.hightech.apidoc.common.commons.httpclient.config.Config;
import com.hightech.apidoc.common.commons.httpclient.handler.HttpRetryHandler;
import org.apache.http.Consts;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.joda.time.DateTime;


/**
 * 默认生成HttpClient的设置
 * 
 * @author user
 * @version $Id: DefaultSettings.java, v 0.1 2015年9月10日 下午5:04:58 user Exp $
 */
public class DefaultConfigs {
	private final static String DEFAULT_CONFIG_KEY = "4c8d748bc9734f58a1511d796295dc55";
	/* 默认的HttpClient配置 */
    private final static Config DEFAULT_CONFIG = createSimpleConfig(DEFAULT_CONFIG_KEY);

    /**
     * Http connection的pool管理器
     * 并提供每5秒钟的自动的无效connection的清理机制
     * 
     * @return PoolingHttpClientConnectionManager
     * 
     */
    public static PoolingHttpClientConnectionManager simpleConnectionPooling() {
        final PoolingHttpClientConnectionManager connManager = 
                new PoolingHttpClientConnectionManager();
        ConnectionConfig connectionConfig = 
                ConnectionConfig.custom().setCharset(Consts.UTF_8).build();
        connManager.setDefaultConnectionConfig(connectionConfig);
        
        connManager.setMaxTotal(500);//最大连接数
        connManager.setDefaultMaxPerRoute(200);//路由最大连接数
        
        SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build();
        connManager.setDefaultSocketConfig(socketConfig);
        
        //5s清理一次过时的connection
        new Timer(true).scheduleAtFixedRate(new TimerTask() {
             @Override
             public void run() {
                 connManager.closeExpiredConnections();
                 connManager.closeIdleConnections(30, TimeUnit.SECONDS);
             }
         }, DateTime.now().toDate(), TimeUnit.SECONDS.toMillis(5));

        return connManager;
    }
    
    /** SSL配置：信任所有 */
    public static SSLContext trustAll() {
        try {
            return new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType)
                        throws CertificateException {
                    return true;
                }
            }).build();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    /** 线程安全的重试处理机制 */
    private static HttpRetryHandler retryHandler() {
    	return new HttpRetryHandler();
    }

    public static Config createSimpleConfig(String key) {
    	/* generated by UUID.randomUUID() */
	    Config config = new Config(key);
	    config.setConnectionManager(simpleConnectionPooling());
	    config.setSslContext(trustAll());
	    config.setRetryHandler(retryHandler());
	    return config;
    }

    static Config get() {
	    return DEFAULT_CONFIG;
    }
}
